package com.wwdeng.smart.video

import android.graphics.SurfaceTexture
import android.text.TextUtils
import android.util.Log
import android.view.Surface
import android.view.TextureView
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.tencent.xnet.XP2P
import com.tencent.xnet.XP2PCallback
import com.wt.monitor.ui.video.utils.Command
import com.wwdeng.smart.app.AppData
import com.wwdeng.smart.base.BaseAct
import com.wwdeng.smart.databinding.ActLocalVideoBinding
import com.wwdeng.smart.utils.TitleBarUtil
import com.wwdeng.smart.video.adapter.VideoLocalAdapter
import com.wwdeng.smart.video.event.ActionRecord
import com.wwdeng.smart.video.event.EventView
import com.wwdeng.smart.video.event.PlaybackFile
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import tv.danmaku.ijk.media.player.IMediaPlayer
import tv.danmaku.ijk.media.player.IjkMediaPlayer
import java.util.Date

/**
 * SmartCamera
 * @Author wwdeng
 * @CreateTime: 2024/11/4 16:58
 * @Annotation：卡回放
 */

private var keepPlayThreadLock = Object()

@Volatile
private var keepAliveThreadRuning = true

class LocalVideoAct : BaseAct(), TextureView.SurfaceTextureListener, EventView, XP2PCallback,
    IMediaPlayer.OnInfoListener, IMediaPlayer.OnErrorListener,IMediaPlayer.OnCompletionListener, CoroutineScope by MainScope() {
    lateinit var binding: ActLocalVideoBinding

    private var isConnected = false
    private var videoPlayer: IjkMediaPlayer? = null
    private var surface: Surface? = null
    private var urlPrefix = ""

    private var localAdapter: VideoLocalAdapter? = null
    override fun getRootView(): View? {
        binding = ActLocalVideoBinding.inflate(layoutInflater)
        return binding.root
    }

    override fun initView() {
        binding.titleLayout.setPadding(0, TitleBarUtil.getStatusBarHeight(), 0, 0)
        binding.txtTitle.text = AppData.deviceName
        initRecyclerView()

        binding.videoView.surfaceTextureListener = this
//        XP2P.startService(this, "${AppData.productId}/${AppData.deviceName}", AppData.productId, AppData.deviceName)
        XP2P.setQcloudApiCred(AppData.accessId, AppData.accessToken)
        XP2P.setCallback(this)

        initLocalPlayerService()
        videoPlayer = IjkMediaPlayer()
        videoPlayer!!.setOnInfoListener(this)
    }

    override fun initListener() {
        binding.imgBack.setOnClickListener {
            finish()
        }
    }

    override fun initData() {
    }

    /**
     * 初始化视频列表
     */
    private fun initRecyclerView() {
        binding.recyclerView.setHasFixedSize(true)
        binding.recyclerView.isNestedScrollingEnabled = false
        binding.recyclerView.isFocusableInTouchMode = false //不需要焦点
        val layoutManager = LinearLayoutManager(this)
        binding.recyclerView.layoutManager = layoutManager
        localAdapter = VideoLocalAdapter(binding.recyclerView)
        localAdapter!!.setOnItemChildClickListener { _, _, position ->
            val item = this.localAdapter!!.getItem(position)
            startPlayLocalVideo(item)
        }
        binding.recyclerView.adapter = localAdapter
    }

    /**
     * 连接服务
     */
    private fun initLocalPlayerService() {
        Thread(Runnable {
            val id = "${AppData.productId}/${AppData.deviceName}"
            var ret = XP2P.startServiceWithXp2pInfo(this, id, AppData.productId, AppData.deviceName, "")
//            val ret = XP2P.setParamsForXp2pInfo(id, AppData.accessId, AppData.accessToken, AppData.xp2pInfo)
            if (ret != 0) {
                launch(Dispatchers.Main) {
                    val errInfo: String
                    if (ret.toString() == "-1007") {
                        errInfo = "APP SDK 版本与设备端 SDK 版本号不匹配，版本号需前两位保持一致"
                    } else {
                        errInfo = "$id 连接错误码 ${ret}，通道断开"
                    }
                    Toast.makeText(this@LocalVideoAct, errInfo, Toast.LENGTH_SHORT).show()
                }
                return@Runnable
            }
            XP2P.delegateHttpFlv(id)?.let {
                Log.e("TAG",">>>>>>>>>>>>>>>>urlPrefix>>>>>>>>>>>>>>>$it")
                urlPrefix = it
                launch(Dispatchers.Main) {
                    loadLocalDataList()
                }
            }
        }).start()
    }

    /**
     * 获取卡回放数据
     */
    private fun loadLocalDataList() {
        Log.e("TAG",">>>>>>>>>>>>>>>>>loadLocalDataList>>>>")
        var id = "${AppData.productId}/${AppData.deviceName}"
        var command = Command.getDayTimeBlocks(0, Date())
        var resp = sendCmd(id, command)

        if (TextUtils.isEmpty(resp)) return
        val json = JSON.parseObject(resp)
        val currentPlaybacks = JSONArray.parseArray(json["file_list"].toString(), PlaybackFile::class.java)
        val localList = arrayListOf<PlaybackFile>()
        if (currentPlaybacks != null) {
            for (item in currentPlaybacks) {
                if (item.file_type == 0) localList.add(item) //只显示视频文件,0：视频，1：图片，其他：自定义
            }
        }
        this.localAdapter!!.data = localList
    }

    private fun sendCmd(id: String, cmd: String): String {
        if (isConnected)
            XP2P.postCommandRequestSync(id, cmd.toByteArray(), cmd.toByteArray().size.toLong(), 2 * 1000 * 1000)?.let {
                return it
            }
        return ""
    }

    /**
     * 播放视频
     */
    private fun startPlayLocalVideo(item: PlaybackFile) {
        val localUrl = urlPrefix + Command.getLocalVideoUrl(0, item.start_time, item.end_time)
        videoPlayer!!.release()

        launch(Dispatchers.Main) {
            binding.videoLayout.removeView(binding.videoView)
            binding.videoLayout.addView(binding.videoView, 0)
        }
        videoPlayer = IjkMediaPlayer()
        videoPlayer!!.setOnInfoListener(this)
        videoPlayer!!.setOnErrorListener(this)
        videoPlayer!!.setOnCompletionListener(this)
        videoPlayer!!.let {
            Log.d("TAG", ">>>>>>>>>>>>>>>>>>>>>>>>>>setPlayerUrl url $localUrl")
            it.reset()

            it.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzemaxduration", 100)
            it.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "probesize", 25 * 1024)
            it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", 0)
            it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 1)
            it.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "threads", 1)
            it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "sync-av-start", 0)
            it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1)
            it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-auto-rotate", 1)
            it.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec-handle-resolution-change", 1)

            it.setSurface(this.surface)
            it.dataSource = localUrl
            it.prepareAsync()
            it.start()
        }
    }

    override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) {
        surface.let {
            this.surface = Surface(surface)
            videoPlayer!!.setSurface(this.surface)
        }
    }

    override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {
    }

    override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {
        return false
    }

    override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {
    }

    override fun eventReady(events: MutableList<ActionRecord>) {
        if (events.size <= 0) {
            Log.e("TAG", "暂无数据")
        }
    }

    override fun fail(msg: String?, errorCode: Int) {
    }

    override fun commandRequest(id: String?, msg: String?) {
    }

    override fun xp2pEventNotify(id: String?, msg: String?, event: Int) {
        Log.e("TAG", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>id=${id}, event=${event}")
        if (event == 1003) {
            Log.e("TAG", "====event === 1003")
            isConnected = false
            keepPlayThreadLock.let {
                synchronized(it) {
                    Log.d("TAG", "====p2p链路断开, event=$event.")
                    it.notify()
                }
            } // 唤醒守护线程
            launch(Dispatchers.Main) {
                var content = "$id 通道断开，正在重连"
                Toast.makeText(this@LocalVideoAct, content, Toast.LENGTH_SHORT).show()
            }
        } else if (event == 1004 || event == 1005) {
//            connectTime = System.currentTimeMillis() - connectStartTime
            if (event == 1004) {
                Log.e("TAG", "====event === 1004")
            }
            isConnected = true
//            launch(Dispatchers.Main) {
//                loadLocalDataList()
//            }
        } else if (event == 1010) {
            Log.e("TAG", "====event === 1010, 校验失败，info撞库防止串流： $msg")
        }
    }

    override fun avDataRecvHandle(id: String?, data: ByteArray?, len: Int) {
    }

    override fun avDataCloseHandle(id: String?, msg: String?, errorCode: Int) {
    }

    override fun onDeviceMsgArrived(id: String?, data: ByteArray?, len: Int): String {
        return "app reply to device"
    }

    override fun onInfo(mp: IMediaPlayer?, what: Int, extra: Int): Boolean {
        return true
    }

    override fun onInfoSEI(mp: IMediaPlayer?, what: Int, extra: Int, sei_content: String?, ): Boolean {
        return false
    }

    override fun onInfoAudioPcmData(mp: IMediaPlayer?, arrPcm: ByteArray?, length: Int) {
    }

    override fun onError(mp: IMediaPlayer?, what: Int, extra: Int): Boolean {
        return true
    }

    /* 播放完成 */
    override fun onCompletion(mp: IMediaPlayer?) {
        Log.e("TAG",">>>>>>>>>>>>>>>play onCompletion")
    }

    private fun finishPlayer() {
//        if (binding.radioTalk.isChecked) speakAble(false)
//        if (binding.radioRecord.isChecked) {
//            videoPlayer.stopRecord()
//            CommonUtils.refreshVideoList(this@VideoPreviewActivity, filePath)
//        }
        videoPlayer!!.release()

//        countDownLatchs.clear()
        // 关闭守护线程
        keepAliveThreadRuning = false
        keepPlayThreadLock.let {
            synchronized(it) {
                it.notify()
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        finishPlayer()
        XP2P.stopService("${AppData.productId}/${AppData.deviceName}")
        XP2P.setCallback(null)
        cancel()
    }
}